// pub fn converter(input: &str) -> String {
//     todo!()
// }

use std::collections::HashMap;
use std::fs::File;
use std::io::{self, BufRead, BufReader};

// 定义转换器结构体
struct PinyinConverter {
    single_char_dict: HashMap<char, Vec<String>>,
    multi_char_dict: HashMap<String, Vec<String>>,
}

impl PinyinConverter {
    // 初始化转换器
    fn new(single_dict_path: &str, multi_dict_path: &str) -> io::Result<Self> {
        Ok(PinyinConverter {
            single_char_dict: Self::load_single_char_dict(single_dict_path)?,
            multi_char_dict: Self::load_multi_char_dict(multi_dict_path)?,
        })
    }

    // 加载单字拼音词典
    fn load_single_char_dict(path: &str) -> io::Result<HashMap<char, Vec<String>>> {
        let file = File::open(path)?;
        let reader = BufReader::new(file);
        let mut dict = HashMap::new();

        for line in reader.lines() {
            let line = line?;
            if let Some((char_str, pinyin_str)) = line.split_once('=') {
                if let Some(ch) = char_str.chars().next() {
                    let pinyins: Vec<String> = pinyin_str
                        .split(',')
                        .map(|s| s.trim().to_string())
                        .collect();
                    dict.insert(ch, pinyins);
                }
            }
        }

        Ok(dict)
    }

    // 加载多字拼音词典
    fn load_multi_char_dict(path: &str) -> io::Result<HashMap<String, Vec<String>>> {
        let file = File::open(path)?;
        let reader = BufReader::new(file);
        let mut dict = HashMap::new();

        for line in reader.lines() {
            let line = line?;
            if let Some((word, pinyin_str)) = line.split_once('=') {
                let pinyins: Vec<String> = pinyin_str
                    .split(',')
                    .map(|s| s.trim().to_string())
                    .collect();
                dict.insert(word.to_string(), pinyins);
            }
        }

        Ok(dict)
    }

    // 转换文本到拼音
    fn convert(&self, text: &str) -> Vec<String> {
        // 首先尝试在多字词典中查找完整词语
        if let Some(pinyins) = self.multi_char_dict.get(text) {
            return pinyins.clone();
        }

        // 如果在多字词典中找不到，则逐字转换
        text.chars()
            .filter_map(|ch| self.single_char_dict.get(&ch))
            .flat_map(|pinyins| pinyins.first().cloned()) // 取每个字的第一个读音
            .collect()
    }
}


// 创建拼音到威妥码的转换器结构体
struct PinyinToWadeGiles {
    mapping: HashMap<String, String>,
}

impl PinyinToWadeGiles {
    // 从文件初始化转换器
    fn new(filename: &str) -> io::Result<Self> {
        let file = File::open(filename)?;
        let reader = BufReader::new(file);
        let mut mapping = HashMap::new();

        // 添加特殊映射关系
        let special_cases = [
            ("si", "ssu"),
            ("zi", "tzu"),
            ("ci", "tz'u"),
            ("chi", "ch'ih"),
            ("shi", "shih"),
            ("ri", "jih"),
            ("zhi", "chih"),
            // 可以继续添加其他特殊映射
        ];

        // 首先添加特殊映射
        for (pinyin, wade_giles) in special_cases.iter() {
            mapping.insert(pinyin.to_string(), wade_giles.to_string());
        }

        // 读取文件并构建映射
        for line in reader.lines() {
            let line = line?;
            let parts: Vec<&str> = line.split_whitespace().collect();
            if parts.len() == 2 {
                let wade_giles = parts[0].to_string();
                let pinyin = parts[1].to_string();
                // 如果不是特殊情况，则添加到映射中
                if !mapping.contains_key(&pinyin) {
                    mapping.insert(pinyin, wade_giles);
                }
            }
        }

        Ok(PinyinToWadeGiles { mapping })
    }

    // 转换拼音到威妥码
    fn convert(&self, pinyin: &str) -> Option<&String> {
        // 首先尝试直接匹配
        if let Some(wade_giles) = self.mapping.get(pinyin) {
            return Some(wade_giles);
        }

        // 如果没有直接匹配，检查是否需要特殊处理
        let pinyin_lower = pinyin.to_lowercase();
        self.mapping.get(&pinyin_lower)
    }

}

fn remove_tone_marks(pinyin: &str) -> String {
    // 创建声调映射表
    let mut tone_marks = HashMap::new();
    
    // 添加声调映射
    tone_marks.insert('ā', 'a'); tone_marks.insert('á', 'a');
    tone_marks.insert('ǎ', 'a'); tone_marks.insert('à', 'a');
    
    tone_marks.insert('ē', 'e'); tone_marks.insert('é', 'e');
    tone_marks.insert('ě', 'e'); tone_marks.insert('è', 'e');
    
    tone_marks.insert('ī', 'i'); tone_marks.insert('í', 'i');
    tone_marks.insert('ǐ', 'i'); tone_marks.insert('ì', 'i');
    
    tone_marks.insert('ō', 'o'); tone_marks.insert('ó', 'o');
    tone_marks.insert('ǒ', 'o'); tone_marks.insert('ò', 'o');
    
    tone_marks.insert('ū', 'u'); tone_marks.insert('ú', 'u');
    tone_marks.insert('ǔ', 'u'); tone_marks.insert('ù', 'u');
    
    tone_marks.insert('ǖ', 'v'); tone_marks.insert('ǘ', 'v');
    tone_marks.insert('ǚ', 'v'); tone_marks.insert('ǜ', 'v');
    tone_marks.insert('ü', 'v');

    // 转换拼音
    pinyin.chars()
        .map(|c| *tone_marks.get(&c).unwrap_or(&c))
        .collect()
}



pub fn converter(input: &str) -> String {
    // 1. 创建所需的转换器
    let pinyin_converter = match PinyinConverter::new("pinyin.dict", "mutil_pinyin.dict") {
        Ok(conv) => conv,
        Err(_) => return String::new(),  // 返回空字符串
    };

    let wade_giles_converter = match PinyinToWadeGiles::new("tw2p.txt") {
        Ok(conv) => conv,
        Err(_) => return "Error: Failed to load Wade-Giles dictionary".to_string(),
    };

    // 2. 转换汉字到拼音
    let pinyins = pinyin_converter.convert(input);
    if pinyins.is_empty() {
        return String::new();
    }

    // 3. 处理每个拼音并转换为威妥码
    let result: Vec<String> = pinyins
        .iter()
        .enumerate() // 添加索引以判断是否是第一个字
        .map(|(index, pinyin)| {
            // 去除声调
            let pinyin_without_tone = remove_tone_marks(pinyin);
            
            // 转换为威妥码
            let wade_giles = wade_giles_converter
                .convert(&pinyin_without_tone)
                .map(|s| s.clone())
                .unwrap_or(pinyin_without_tone);

            // 如果是第一个字，将首字母大写
            if index == 0 {
                capitalize_first(&wade_giles)
            } else {
                wade_giles
            }
        })
        .collect();

    // 4. 合并结果
    result.join(" ")
}

// 首字母大写辅助函数
fn capitalize_first(s: &str) -> String {
    let mut chars = s.chars();
    match chars.next() {
        None => String::new(),
        Some(first_char) => {
            first_char.to_uppercase().collect::<String>() + chars.as_str()
        }
    }
}
